package controllers

import (
	"fmt"
	"time"
	"regexp"
	"strings"
	"strconv"
	"net/http"
	"meman/models/events"
	"meman/libs/paginator"
	"meman/models/alert"
	"meman/models/auth"
	"meman/sys/basic"
	"meman/sys/rpclient"
	"meman/libs/utils"
	"github.com/labstack/echo"
	"github.com/chaosue/echo-sessions"
	"github.com/labstack/echo/engine/standard"
)

//TODO cfg service的一个值,先写在这里,到时候要改Service的配置文件的时候移过去,但是没有使用,未查到哪里使用
//const MAX_MESSAGE_DELIVERY_TIME  = 5

func SubscriptionListShow(c echo.Context) error  {

	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	//使用临时session存储保存消息
	alertInfo := new(alert.Alert)
	if flashes := session.Flashes("alertInfo"); len(flashes) > 0 {
		alertInfo = flashes[0].(*alert.Alert)
	}
	session.Save()

	logger := basic.Logger{}

	var perPageNums = 0
	per := c.QueryParam("perPageNums")
	if per != "" {
		num,err := strconv.Atoi(per)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "perPageNums转换int失败!") }
		}else {
			perPageNums = num
		}

	}

	subscriberKey := c.QueryParam("subscriber_key")
	classKey := c.QueryParam("class_key")
	conds := make(map[string]interface{})
	if subscriberKey != "" {
		conds["subscriber_key"] = subscriberKey
	}
	if classKey != "" {
		conds["class_key"] = classKey
	}

	//获取订阅者
	subscriber := events.Subscriber{}
	subscribers,err := subscriber.GetNames()
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查询订阅者失败!") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionListShow]search subscriber name error!", username))
	}

	//获取消息分类
	message := events.Message{}
	db := basic.Read()
	messageClasses,err := message.GetMsgList(db, nil, 0, 999999999)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, ",查询消息分类失败!") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionListShow]can not get msgList!", username))
	}

	//获取订阅
	subscription := events.Subscription{}
	db, count := subscription.Count(conds)
	p := paginator.NewPaginator(c.Request().(*standard.Request).Request, perPageNums, count)
	result, err := subscription.GetSubscriptionList(db, conds, p.Page(), p.PerPageNums)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查询失败请检查")}
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionListShow]can not get subscriptionList!", username))
	}

	c.Render(http.StatusOK, "subscriptionList.tmpl", basic.H{
		"name":username,
		"data": result,
		"subscribers":subscribers,
		"messageClasses":messageClasses,
		"subscriberKey":subscriberKey,
		"classKey":classKey,
		"query":conds,
		"paginator": p,
		"alert":alertInfo,
	})

	return nil

}


//添加订阅管理跳转
func SubscriptionAdd(c echo.Context) error {
	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	//使用临时session存储保存消息
	alertInfo := new(alert.Alert)
	if flashes := session.Flashes("alertInfo"); len(flashes) > 0 {
		alertInfo = flashes[0].(*alert.Alert)
	}
	session.Save()

	logger := basic.Logger{}


	//获取订阅者
	subscriber := events.Subscriber{}
	subscribers,err := subscriber.GetListByCond(map[string]interface{}{ "status":0 })
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, ",查询订阅者失败!") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAdd]can not get subscriberList by conds!", username))
	}

	//获取消息分类
	message := events.Message{}
	db := basic.Read()
	messageClasses,err := message.GetMsgList(db, nil, 0, 999999999)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查询消息分类失败!") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAdd]can not get msgList!", username))
	}

	var defaultParams interface{}
	client, err := rpclient.New(basic.Config.ListenAddr)
	defer client.Close()
	if err != nil {
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAdd]rpc client connect error:%s",username, err))
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("rpc client connect error:%s", err)) }
	}else {
		defaultParams, err = client.Call("GetDefaultSubscriptionSettings", map[string]interface{}{})
		if err != nil {
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAdd]rpc call GetDefaultSubscriptionSettings error:",username, err))
		}
	}

	c.Render(http.StatusOK, "subscriptionAdd.tmpl", basic.H{
		"name":username,
		"subscribers":subscribers,
		"messageClasses":messageClasses,
		"defaultParams":defaultParams,
		//"defaultTimeOut":MAX_MESSAGE_DELIVERY_TIME,
		"alert":alertInfo,
	})

	return nil
}
//处理添加
func SubscriptionAddPost(c echo.Context) error  {
	//session 使用
	session := sessions.Default(c)
	var username string
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	alertInfo := new(alert.Alert)
	logger := basic.Logger{}


	subscription, subParams, alertInfo := validateInpputData(c)
	if !alertInfo.Flag {
		c.Render(http.StatusOK, "subscriptionAdd.tmpl", basic.H{
			"name":username,
			//"defaultTimeOut":MAX_MESSAGE_DELIVERY_TIME,
			"alert":alertInfo,
		})

	}

	// class_key 好像没有使用所以可以不传过来
	//因为前端是radio 所以应该是不能多选的,所以ids永远传递的是一个值,除非改为多选
	messageClassId := utils.TrimSpace(c.FormValue("class_id"))
	if messageClassId != "" {
		ok,err := events.Exists(messageClassId, "class_id", events.TABLE_MSG_CLASSES)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, err.Error()) }
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAddPost]can not find classId:%s",username, err))
		}
		if !ok {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "没有该消息类型!")  }
		}

		//添加消息类型id
		subscription.MessageClassId,err = strconv.Atoi(messageClassId)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "subscription MessageClassId 转换int失败!")  }
		}

		db := basic.Read()
		conds := map[string]interface{}{
			"subscriptions.subscriber_id":subscription.SubscriberId,
		}
		subscriptionList,err := subscription.GetSubscriptionList(db, conds, 0, 999999999)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("subscriptionList 获取失败:%s"), err.Error())  }
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAddPost]getSubscription error:%s",username, err))
		}

		subExists := false
		for _, sub := range subscriptionList  {
			if subscription.MessageClassId == sub.MessageClassId &&
			subscription.ReceptionChannel == sub.ReceptionChannel {
				subExists = true
			}
		}

		// 注意api调用顺序.
		client, err := rpclient.New(basic.Config.ListenAddr)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("rpc client connect error:%s", err.Error())) }
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAddPost]rpc client connect error:%s",username, err))
		}
		defer client.Close()
		var re interface{}


		if subExists {
			//如果已经存在就直接返回填充成功
			alertInfo = &alert.Alert{Flag:true, Msg:append(alertInfo.Msg, "该订阅已存在") }
		}else {
			err :=subscription.Insert()
			if err != nil {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("subscription insert失败:%s", err))  }
				logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAddPost]subscription insert error:%s",username, err))
			}else {

				subscriptionId := subscription.SubscriptionId
				if subscriptionId >= 0 {
					//TODO 这块的类型不正确, 需要确认一下类型,然后重新组装 subParams 确认类型后, 然后在下面参数进行保存设置
					re, err := client.Call("SetSubscriptionParams", map[string]interface{}{
						"SubscriptionId": subscriptionId,
						"Params":subParams,
					})
					if err != nil {
						alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, err.Error()) }
						logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAddPost]rpc call SetSubscriptionParams error:%s",username, err))
					} else {
						logger.WriteMsg("info", fmt.Sprintf("[%s][SubscriptionAddPost]rpc SetSubscriptionParams:%q",username, re))
					}

					subParamsTmp := make(map[string]string)
					//数据库该数据类型都为string
					for k, v := range subParams  {
						subParamsTmp[k] = fmt.Sprintf("%s", v)
					}

					err = subscription.SaveSubscriptionParams(subscriptionId, subParamsTmp)
					if err != nil {
						alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("保存subscription_params 失败:%s", err)) }
						logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAddPost]subscription_params save error:%s",username, err))
					} else {
						alertInfo = &alert.Alert{Flag:true, Msg:append(alertInfo.Msg, "添加成功!") }
					}

				}else {
					alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "保存失败!") }
				}



			}

		}

		if alertInfo.Flag {
			re, err = client.Call("ClearDataCache", map[string]interface{}{})
			if re != true {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "Not cleared") }
				logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionAddPost]rpc ClearDataCache Not cleared:%s",username, err))
			}
		}

	} else {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "消息类型不能为空!") }
	}

	session.AddFlash(alertInfo, "alertInfo")
	session.Save()

	c.Redirect(http.StatusFound,"/Event/Subscription/add")


	return nil
}


//更新跳转
func SubscriptionUpdate(c echo.Context) error  {
	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	id := c.QueryParam("id")
	subscriptionId,err := strconv.Atoi(id)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "subscription id 转换int失败!")}
	}

	subscription := events.Subscription{}
	subscriptionDetail, err := subscription.GetSubscriptionDetail(subscriptionId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查找订阅者失败")}
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdate]can not find subscriptionDetail:%s",username, err))
	}

	var subscriptionResult events.SubscriptionResult
	if len(subscriptionDetail) == 1 {
		subscriptionResult = subscriptionDetail[0]
	}else {
		c.Render(http.StatusOK, "errors.tmpl", basic.H{
			"errorMessage": "不存在的订阅.",
		})
	}

	client, err := rpclient.New(basic.Config.ListenAddr)
	defer client.Close()


	var subParamsCached interface{}
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("rpc client connect error:%s", err)) }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdate]rpc client connect error:%s",username, err))
	}else {
		subParamsCached, err = client.Call("GetSubscriptionParams", map[string]interface{}{
			"SubscriptionId": subscriptionId,
		})
		if err != nil {
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdate]rpc GetSubscriptionParams error:%s",username, err))
		}

	}

	subParams,err := subscription.GetSubscriptionParams(subscriptionId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("subscription params 查询失败:%s", err.Error()))}
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdate]get subscriptionParams error:%s",username, err))
	}
	if len(subParams) > 1 {
		subParamsCached = subParams
	}

	//获取订阅者
	subscriber := events.Subscriber{}
	subscribers,err := subscriber.GetListByCond(map[string]interface{}{ "status":0 })
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, ",查询订阅者失败!") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdate]get subscriber by conds error:%s",username, err))
	}

	//获取消息分类
	message := events.Message{}
	db := basic.Read()
	messageClasses,err := message.GetMsgList(db, nil, 0, 999999999)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "查询消息分类失败!") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdate]get msgList error:%s",username, err))
	}

	var defaultParams interface{}
	defaultParams, err = client.Call("GetDefaultSubscriptionSettings", map[string]interface{}{})
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "rpc 获取defaultParams 失败!") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdate]rpc call GetDefaultSubscriptionSettings error:%s",username, err))
	}

	c.Render(http.StatusOK, "subscriptionUpdate.tmpl", basic.H {
		"name":username,
		"subscribers":subscribers,
		"messageClasses":messageClasses,
		"subscriptionDetail": subscriptionResult,
		"subParams":subParamsCached,
		"defaultParams":defaultParams,
		"alert":alertInfo,
	})

	return nil

}

func SubscriptionUpdatePost(c echo.Context) error {
	//session 使用
	session := sessions.Default(c)
	var username string
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	subscription, subParams, alertInfo := validateInpputData(c)
	if !alertInfo.Flag {
		c.Render(http.StatusOK, "subscriptionAdd.tmpl", basic.H{
			"name":username,
			//"defaultTimeOut":MAX_MESSAGE_DELIVERY_TIME,
			"alert":alertInfo,
		})

	}

	subscriptionId := utils.TrimSpace(c.FormValue("subscription_id"))
	subscriptionIdInt,err := strconv.Atoi(subscriptionId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "subscription id 转换int失败!")}
	}

	//TODO 这部分可以放到 validateInpputData 中应该
	messageClassId := utils.TrimSpace(c.FormValue("class_id"))
	if messageClassId != "" {
		ok,err := events.Exists(messageClassId, "class_id", events.TABLE_MSG_CLASSES)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, err.Error()) }
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdatePost]class_id not Exist:%s",username, err))
		}
		if !ok {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "没有该消息类型!")  }
		}

		//添加消息类型id
		subscription.MessageClassId,err = strconv.Atoi(messageClassId)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "subscription MessageClassId 转换int失败!")  }
		}


		// 注意api调用顺序.
		client, err := rpclient.New(basic.Config.ListenAddr)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("rpc client connect error:%s", err.Error())) }
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdatePost]rpc client connect error:%s",username, err))
		}
		defer client.Close()
		var re interface{}

		err = subscription.Update(subscriptionIdInt)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("subscription update失败:%s"), err.Error())  }
			logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdatePost]subscription update error:%s",username, err))
		}else {

			//TODO 这块的类型不正确, 需要确认一下类型,然后重新组装 subParams 确认类型后, 然后在下面参数进行保存设置
			_, err := client.Call("SetSubscriptionParams", map[string]interface{}{
				"SubscriptionId": subscriptionIdInt,
				"Params":subParams,
			})
			if err != nil {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, err.Error()) }
				logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdatePost]rpc call SetSubscriptionParams error:%s",username, err))
			}

			subParamsTmp := make(map[string]string)
			//数据库该数据类型都为string
			for k, v := range subParams  {
				subParamsTmp[k] = fmt.Sprintf("%s", v)
			}

			err = subscription.SaveSubscriptionParams(subscriptionIdInt, subParamsTmp)
			if err != nil {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("修改subscription_params 失败:%s"), err.Error()) }
				logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdatePost]SubscriptionParams save error:%s",username, err))
			} else {
				alertInfo = &alert.Alert{Flag:true, Msg:append(alertInfo.Msg, "修改成功!") }
				logger.WriteMsg("info", fmt.Sprintf("[%s][SubscriptionUpdatePost]SubscriptionParams save:%s",username, err))
			}

		}

		if alertInfo.Flag {
			re, err = client.Call("ClearDataCache", map[string]interface{}{})
			if re != true {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "Not cleared") }
				logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionUpdatePost]rpc call ClearDataCache error:%s",username, err))
			}
		}

	} else {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "消息类型不能为空!") }
	}

	session.AddFlash(alertInfo, "alertInfo")
	session.Save()

	c.Redirect(http.StatusFound, "/Event/Subscription/update?id="+ subscriptionId )

	return nil
}

//删除
func SubscriptionDelete(c echo.Context) error  {

	//session 使用
	session := sessions.Default(c)
	var username string
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	id := c.QueryParam("id")
	subscriptionId,err := strconv.Atoi(id)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "id 转换int失败!") }
	}

	subscription := events.Subscription{}
	err = subscription.DeleteById(subscriptionId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("delete by id error:id:%s, err:%s",id, err )) }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionDelete]subscription DeleteById error:id:%s, error:%s",username,id, err))
	}

	err = subscription.ClearSubscriptionParams(subscriptionId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("ClearSubscriptionParams error:id:%s, err:%s",id, err )) }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionDelete]subscription ClearSubscriptionParams error:id:%s, error:%s",username,id, err))
	}

	client, err := rpclient.New(basic.Config.ListenAddr)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("rpc client connect error:%s", err.Error())) }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionDelete]rpc client connect error:%s",username, err))
	}
	defer client.Close()
	var re interface{}
	re, err = client.Call("ClearDataCache", map[string]interface{}{})
	if re != true {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "Not cleared") }
		logger.WriteMsg("error", fmt.Sprintf("[%s][SubscriptionDelete]rpc call ClearDataCache error:%s",username, err))
	}

	session.AddFlash(alertInfo, "alertInfo")
	session.Save()

	c.Redirect(http.StatusFound,"/Event/MsgList/show")

	return nil
}




/**
@return events.Subscription subScription类,返回该类进行相应操作
@return map[string][string] events.SubscriptionParams 中 param的key 和 value 都为string类型
@return alert.Alert 返回错误消息
 */
func validateInpputData(c echo.Context) (events.Subscription, map[string]interface{}, *alert.Alert)  {

	alertInfo := new(alert.Alert)
	alertInfo.Flag = true

	logger := basic.Logger{}

	//rpc defaultSettings
	client, err := rpclient.New(basic.Config.ListenAddr)
	defer client.Close()
	var reponse interface{}
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg,fmt.Sprintf("rpc client connect error:%s", err)) }
		logger.WriteMsg("error", fmt.Sprintf("[validateInpputData]rpc client connect error:%s", err))
	}else {
		reponse, err = client.Call("GetDefaultSubscriptionSettings", map[string]interface{}{})
	}

	subscriberId := utils.TrimSpace(c.FormValue("subscriber_id"))
	subscriberIdInt,err := strconv.Atoi(subscriberId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "subscriberId转换int错误") }
	}
	timeout := utils.TrimSpace(c.FormValue("timeout"))
	timeoutInt,err := strconv.Atoi(timeout)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "超时转换int错误") }
	}
	status := utils.TrimSpace(c.FormValue("status"))
	statusInt,err := strconv.Atoi(status)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "状态转换int错误") }
	}

	subscription := events.Subscription{
		SubscriberId:subscriberIdInt,
		Timeout:timeoutInt/1000,
		ReceptionChannel:utils.TrimSpace(c.FormValue("reception_channel")),
		Status:statusInt,
	}

	//update 验证是否有id
	subscriptionId := utils.TrimSpace(c.FormValue("subscription_id"))
	if subscriptionId != "" {
		subscription.SubscribeTime = time.Now().Unix()
	}

	if subscriberId == "" {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "请选择订阅者")}
	}
	exist, err := events.Exists(subscriberId, "subscriber_id", events.TABLE_SUBSCRIBERS)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "subscriber Exists() error!")}
	}
	if !exist {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "订阅者不存在")}
	}else {
		reg := regexp.MustCompile(`\n|\r\n|\r`)
		receptionChannelArray := reg.Split(strings.Trim(subscription.ReceptionChannel," "),-1)
		for k, url := range receptionChannelArray  {
			receptionChannelArray[k] = strings.Trim(url, " ")
			regUrl := regexp.MustCompile(`/^(\[.+?\])*https?:\/\//i`);
			if regUrl.MatchString(url) {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("消息处理地址(%s)格式不正常", url))}
			}
		}
		subscription.ReceptionChannel = strings.Join(receptionChannelArray, "\n")
	}



	subParams := make(map[string]interface{})

	concurrency := utils.TrimSpace(c.FormValue("concurrency"))
	subParams["Concurrency"] = concurrency

	concurrencyOfRetry := utils.TrimSpace(c.FormValue("concurrency_as_retry"))
	subParams["ConcurrencyOfRetry"] = concurrencyOfRetry

	intervalOfSending := utils.TrimSpace(c.FormValue("interval_of_pushes"))
	subParams["IntervalOfSending"] = intervalOfSending

	processTimeout := utils.TrimSpace(c.FormValue("timeout"))
	subParams["ProcessTimeout"] = processTimeout

	subParams["ReceptionUri"] = subscription.ReceptionChannel

	alerterPhoneNumbers := utils.TrimSpace(c.FormValue("alerter_tel"))
	subParams["AlerterPhoneNumbers"] = alerterPhoneNumbers

	alerterEmails := utils.TrimSpace(c.FormValue("alerter_email"))
	subParams["AlerterEmails"] = alerterEmails

	alerterEnabled := utils.TrimSpace(c.FormValue("alerter_enabled"))
	subParams["AlerterEnabled"] = alerterEnabled


	if alerterEmails != "" {
		emailArray := strings.Split(alerterEmails, ",")
		for _, email := range emailArray  {
			if !utils.IsEmail(email) {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("电子邮箱(%s)格式非法！", email))}
			}
		}
	}
	if alerterPhoneNumbers != "" {
		emailArray := strings.Split(alerterPhoneNumbers, ",")
		for _, tel := range emailArray  {
			if !utils.IsPhone(tel) {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("电话号码(%s)格式非法！", tel))}
			}
		}
	}


	/**
	-------------------------------------
	这部分类型推断新版本已经改变
	 */
	defaultSettings := reponse.(map[string]interface{})


	maxSendersPerChannel := int(defaultSettings["MaxSendersPerChannel"].(float64))
	maxSendersPerRetryChannel := int(defaultSettings["MaxSendersPerRetryChannel"].(float64))
	maxMessageProcessTime := int(defaultSettings["MaxMessageProcessTime"].(float64))

	/**

	end
	-------------------------------------
	*/


	concurrencyInt,err := strconv.Atoi(concurrency)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "concurrency转换int失败!") }
	}
	if concurrencyInt > maxSendersPerChannel {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "推送并发数超过最大限制！")}
	}

	concurrencyOfRetryInt,err := strconv.Atoi(concurrencyOfRetry)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "concurrencyOfRetryInt转换int失败!") }
	}
	if concurrencyOfRetryInt > maxSendersPerRetryChannel {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "(重试队列)推送并发数\"超过最大限制！")}
	}

	processTimeoutInt,err := strconv.Atoi(processTimeout)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "processTimeoutInt转换int失败!") }
	}
	if processTimeoutInt > maxMessageProcessTime {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "消息处理超时\"超过最大限制")}
	}else if processTimeoutInt == 0  {
		subParams["ProcessTimeout"] = strconv.Itoa(maxMessageProcessTime)
	}

	intervalOfSendingInt,err := strconv.Atoi(processTimeout)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "processTimeoutInt转换int失败!") }
	}
	if intervalOfSendingInt <= 0  {
		subParams["IntervalOfSending"] = strconv.Itoa(0)
	}


	/**
	-------------------------------------
	这部分类型推断新版本已经改变, subscriptionParams 类型转换
	 */

	subParams["ConcurrencyOfRetry"],_ = strconv.ParseFloat(subParams["Concurrency"].(string), 64)
	subParams["Concurrency"],_ = strconv.ParseFloat(subParams["Concurrency"].(string), 64)
	subParams["IntervalOfSending"],_ = strconv.ParseFloat(subParams["IntervalOfSending"].(string), 64)
	subParams["ProcessTimeout"],_ = strconv.ParseFloat(subParams["ProcessTimeout"].(string), 64)
	if subParams["AlerterEnabled"] != 0 {
		subParams["AlerterEnabled"] = true
	}else {
		subParams["AlerterEnabled"] = false
	}
	/**

	end
	-------------------------------------
	*/



	return subscription, subParams, alertInfo

}





